﻿// using System;
// using System.Collections.Concurrent;
// using System.Collections.Generic;
// using System.Net;
// using System.Net.Sockets;
// using System.Text;
// using System.Threading;
// using MemoryPack;
// using Sirenix.OdinInspector;
// using UnityEngine;
//
// namespace Hsenl.Network {
//     public class NetworkTest : MonoBehaviour {
//         public enum ProtocolKind {
//             Tcp,
//             Kcp
//         }
//
//         public static NetworkTest Instance;
//
//         public ProtocolKind protocol;
//         public bool checkMsgAccuracy;
//
//         private NetworkServer _server;
//         private List<NetworkClient> _clients = new();
//
//         public static long c2s_ms;
//         public static long c2s_ms_sum;
//         public static long c2s_ms_count;
//         public static long c2s_ms_big_count;
//         public static long s2c_ms;
//         public static long s2c_ms_sum;
//         public static long s2c_ms_count;
//         public static long s2c_ms_big_count;
//
//         public static int c2s_sendCounter;
//         public static int c2s_recvCounter;
//         public static int s2c_sendCounter;
//         public static int s2c_recvCounter;
//
//         public static int c2s_sendCounter2;
//         public static int c2s_recvCounter2;
//         public static int s2c_sendCounter2;
//         public static int s2c_recvCounter2;
//
//         public static ConcurrentDictionary<long, ConcurrentQueue<C2R_Say>> sayQueue = new();
//
//         private long timer;
//         public StringBuilder stringBuilder = new();
//
//         [Button("创建客户端")]
//         public void NewClient() {
//             this.CreateClient();
//         }
//
//         [Button("创建5个客户端")]
//         public void NewClient2() {
//             for (int i = 0; i < 5; i++) {
//                 this.CreateClient();
//             }
//         }
//
//         [Button("创建50个客户端")]
//         public void NewClient3() {
//             for (int i = 0; i < 50; i++) {
//                 this.CreateClient();
//             }
//         }
//
//         [Button("创建100个客户端")]
//         public void NewClient4() {
//             for (int i = 0; i < 100; i++) {
//                 this.CreateClient();
//             }
//         }
//
//         private void Start() {
//             Instance = this;
//             SceneManager.LoadScene("main", LoadSceneMode.Single);
//
//             this.CreateServer();
//             // this.CreateClient();
//         }
//
//         private void CreateServer() {
//             // server
//             Acceptor server;
//             switch (this.protocol) {
//                 case ProtocolKind.Tcp:
//                     server = new TcpServer(new TcpServer.Configure() {
//                         LocalIPHost = "127.0.0.1",
//                         Port = 12312,
//                         RecvBufferSize = 1024 * 64,
//                         SendBufferSize = 1024 * 64, // 根据情况, 网关可以大些(x128 ~ x256)
//                         RecvBufferSizePer = 1024 * 3, // 网关 * 30
//                         SendBufferSizePer = 1024 * 1, // 网关 * 10
//                         Backlog = 1000,
//                         NoDelay = true,
//                     });
//                     break;
//                 case ProtocolKind.Kcp:
//                     server = new KcpServer(new KcpServer.Configure() {
//                         LocalIPHost = "127.0.0.1",
//                         Port = 12312,
//                         RecvBufferSize = 1024 * 512,
//                         SendBufferSize = 1024 * 512,
//                         Backlog = 1000,
//                     });
//                     break;
//                 default:
//                     throw new ArgumentOutOfRangeException();
//             }
//
//             server.OnRecvDataEvent += (l, memory) => {
//                 // Log.Info($"server recv data succ. channel:{l}  memory_len:{memory.Length} string:{getstring(memory)}");
//                 // Log.Info($"server recv data succ. channel:{l}  memory_len:{memory.Length}");
//                 Interlocked.Increment(ref c2s_recvCounter2);
//             };
//             server.OnSendDataEvent += (l, memory) => {
//                 // Log.Info($"server send data succ. channel:{l}  memory_len:{memory.Length}");
//                 Interlocked.Increment(ref s2c_sendCounter2);
//             };
//             // server.OnMessageReadedEvent += (l, memory) => {
//             //     Log.Info($"server read data succ. channel:{l}  memory_len:{memory.Length} string:{getstring(memory)}");
//             // };
//
//             // server.OnErrorEvent += (l, i) => { Debug.LogError($"server error: {i}"); };
//
//             var encryptionPlug = new DefaultEncryptionPlug();
//             server.AddPlug<IAfterMessageReaded, EncryptionPlug>(encryptionPlug);
//             server.AddPlug<IAfterMessageWrited, EncryptionPlug>(encryptionPlug);
//             TrafficMonitoringPlug trafficMonitoringPlug = new();
//             server.AddPlug<IOnChannelStarted, TrafficMonitoringPlug>(trafficMonitoringPlug);
//             server.AddPlug<IOnChannelDisconnected, TrafficMonitoringPlug>(trafficMonitoringPlug);
//             server.AddPlug<IAfterMessageReaded, TrafficMonitoringPlug>(trafficMonitoringPlug);
//             server.AddPlug<IAfterMessageWrited, TrafficMonitoringPlug>(trafficMonitoringPlug);
//             // server.AddPlug<IOnChannelStarted, KeepalivePlug>(new KeepalivePlug(10));
//             this._server = Entity.Create(server.GetType().Name).AddComponent<NetworkServer>();
//             this._server.Start(server);
//         }
//
//         private void CreateClient() {
//             // client
//             Connector client;
//             switch (this.protocol) {
//                 case ProtocolKind.Tcp:
//                     client = new TcpClient(new TcpClient.Configure() {
//                         RemoteIPHost = "127.0.0.1",
//                         Port = 12312,
//                         RecvBufferSize = 1024 * 64,
//                         SendBufferSize = 1024 * 64,
//                         RecvBufferSizePer = 1024 * 3,
//                         SendBufferSizePer = 1024 * 1,
//                         NoDelay = true,
//                     });
//                     break;
//                 case ProtocolKind.Kcp:
//                     client = new KcpClient(new KcpClient.Configure() {
//                         RemoteIPHost = "127.0.0.1",
//                         Port = 12312,
//                         RecvBufferSize = 1024 * 512,
//                         SendBufferSize = 1024 * 512,
//                     });
//                     break;
//                 default:
//                     throw new ArgumentOutOfRangeException();
//             }
//
//             client.OnRecvDataEvent += (l, memory) => {
//                 // Log.Info($"server recv data succ. channel:{l}  memory_len:{memory.Length}");
//                 Interlocked.Increment(ref s2c_recvCounter2);
//             };
//             client.OnSendDataEvent += (l, memory) => {
//                 // Log.Info($"client send data succ. channel:{l}  memory_len:{memory.Length} string:{getstring(memory)}");
//                 // Log.Info($"client send data succ. channel:{l}  memory_len:{memory.Length}");
//                 Interlocked.Increment(ref c2s_sendCounter2);
//             };
//             // client.OnMessageReadedEvent += (l, memory) => {
//             //     Log.Info($"client read data succ. channel:{l}  memory_len:{memory.Length}");
//             // };
//             // client.OnMessageWritedEvent += (l, memory) => {
//             //     Log.Info($"client write data succ. channel:{l}  memory_len:{memory.Length} string:{getstring(memory)}");
//             // };
//
//             // client.OnErrorEvent += (l, i) => { Debug.LogError($"client error {(SocketError)i}"); };
//
//             var encryptionPlug = new DefaultEncryptionPlug();
//             client.AddPlug<IAfterMessageReaded, EncryptionPlug>(encryptionPlug);
//             client.AddPlug<IAfterMessageWrited, EncryptionPlug>(encryptionPlug);
//             // client.AddPlug<IOnChannelDisconnected, ReconnectPlug>(new ReconnectPlug());
//             var c = Entity.Create(client.GetType().Name).AddComponent<NetworkClient>();
//             c.Start(client).Tail();
//             this._clients.Add(c);
//         }
//
//         private async void Login(NetworkClient client) {
//             var now = TimeInfo.Now;
//             var response = await client.Call(new C2R_Login() {
//                 account = "duanchunzeduanchunze",
//                 password = "aga;jag;dfa;lg;a"
//             }).As<R2C_Login>();
//             Debug.LogWarning(response.ip + $"总耗时: {TimeInfo.Now - now} 线程: {Thread.CurrentThread.ManagedThreadId}");
//         }
//
//         public async hvoid Ping(NetworkClient client, string msg = null) {
//             Interlocked.Increment(ref c2s_sendCounter);
//
//             var now = DateTime.Now.Ticks / 10000;
//
//             using var requeset = Network.MessagePool.Rent<C2R_Ping>();
//             requeset.sendDT = now;
//             requeset.str = msg;
//             var rpc = client.Call(requeset);
//             using var response = Network.MessagePool.Rent<R2C_Ping>();
//             await rpc.AsWithMultiThread(response);
//
//             var now2 = DateTime.Now.Ticks / 10000;
//             var ms = now2 - response.responseDT;
//             s2c_ms_sum += ms;
//             s2c_ms_count += 1;
//             s2c_ms = s2c_ms_sum / s2c_ms_count;
//             if (ms > 100) {
//                 s2c_ms_big_count++;
//             }
//
//             Interlocked.Increment(ref s2c_recvCounter);
//             // Debug.Log($"Ping 总耗时: {now2 - now} " +
//             //                   $"发送耗时: {response.sendTC} " +
//             //                   $"接收耗时: {now2 - response.responseDT} " +
//             //                   $"线程: {Thread.CurrentThread.ManagedThreadId}");
//         }
//
//         // 测试单个连接, 消息数吞吐
//         public void Say(NetworkClient client, string msg = null) {
//             var now = DateTime.Now.Ticks / 10000;
//             Interlocked.Increment(ref c2s_sendCounter);
//             var say = new C2R_Say { sendDT = now, msg = msg };
//             if (this.checkMsgAccuracy) {
//                 if (!sayQueue.TryGetValue(client.Service.GetChannel(0).ChannelId, out var queue)) {
//                     queue = new ConcurrentQueue<C2R_Say>();
//                     sayQueue.TryAdd(client.Service.GetChannel(0).ChannelId, queue);
//                 }
//
//                 queue.Enqueue(say);
//             }
//
//             client.Notif(say);
//         }
//
//         public string GetRandomStr(int min, int max) {
//             this.stringBuilder.Clear();
//             var r = RandomHelper.NextInt(min, max);
//             for (int i = 0; i < r; i++) {
//                 this.stringBuilder.Append("1");
//             }
//
//             return this.stringBuilder.ToString();
//         }
//
//         private void Run() {
//             if (InputController.GetButtonDown(InputCode.L)) {
//                 for (int i = 0; i < this._clients.Count; i++) {
//                     var client = this._clients[i];
//                     if (!client.IsConnected) {
//                         this._clients.RemoveAt(i);
//                         if (!client.IsDisposed)
//                             client.Entity.Active = false;
//                         i--;
//                         continue;
//                     }
//
//                     for (int j = 0; j < 100; j++) {
//                         // this.Ping(client, this.GetRandomStr(10, 100)).Tail();
//                     }
//
//                     for (int j = 0; j < 100; j++) {
//                         this.Say(client, this.GetRandomStr(10, 50));
//                         // this.Say(client);
//                     }
//                 }
//             }
//
//             if (InputController.GetButton(InputCode.K)) {
//                 for (int i = 0; i < this._clients.Count; i++) {
//                     var client = this._clients[i];
//                     if (!client.IsConnected) {
//                         this._clients.RemoveAt(i);
//                         if (!client.IsDisposed)
//                             client.Entity.Active = false;
//                         i--;
//                         continue;
//                     }
//
//                     for (int j = 0; j < 100; j++) {
//                         this.Ping(client, this.GetRandomStr(10, 100)).Tail();
//                     }
//
//                     for (int j = 0; j < 100; j++) {
//                         // this.Say(client, this.GetRandomStr(10, 50));
//                         // this.Say(client);
//                     }
//
//                     for (int j = 0; j < 2; j++) {
//                         // this.Say(client, this.GetRandomStr(1200, 1200));
//                     }
//                 }
//             }
//         }
//
//         private void Update() {
//             this.Run();
//
//             if (TimeInfo.Now < this.timer)
//                 return;
//
//             this.timer = TimeInfo.Now + 1000;
//
//             if (c2s_ms > 0 || s2c_ms > 0 || c2s_ms_big_count > 0 || s2c_ms_big_count > 0) {
//                 Debug.Log($"客户端到服务端耗时: {c2s_ms}ms,  服务端到客户端耗时: {s2c_ms}ms");
//                 Debug.Log($"客户端到服务端大延迟次数: {c2s_ms_big_count}/{c2s_ms_count},  服务端到客户端大延迟次数: {s2c_ms_big_count}/{s2c_ms_count}");
//                 c2s_ms = 0;
//                 s2c_ms = 0;
//                 c2s_ms_sum = 0;
//                 c2s_ms_count = 0;
//                 s2c_ms_sum = 0;
//                 s2c_ms_count = 0;
//                 c2s_ms_big_count = 0;
//                 s2c_ms_big_count = 0;
//             }
//
//             if (c2s_sendCounter > 0 || c2s_recvCounter > 0 || s2c_sendCounter > 0 || s2c_sendCounter > 0)
//                 Debug.Log($"客户端到服务端消息数: 发送:{c2s_sendCounter} - 接收:{c2s_recvCounter}, 服务端到客户端消息数: 发送:{s2c_sendCounter} - 接收:{s2c_recvCounter}");
//
//             if (c2s_sendCounter2 > 0 || c2s_recvCounter2 > 0 || s2c_sendCounter2 > 0 || s2c_sendCounter2 > 0)
//                 Debug.Log($"客户端到服务端包数: 发送:{c2s_sendCounter2} - 接收:{c2s_recvCounter2}, 服务端到客户端包数: 发送:{s2c_sendCounter2} - 接收:{s2c_recvCounter2}");
//         }
//
//         private void OnDestroy() {
//             if (this._server is { IsDisposed: false })
//                 Object.Destroy(this._server.Entity);
//             foreach (var client in this._clients) {
//                 if (client is { IsDisposed: false }) {
//                     Object.Destroy(client.Entity);
//                 }
//             }
//         }
//
//         private string getstring(Memory<byte> memory) {
//             var count = memory.Length;
//             Span<byte> span = memory.Span;
//             StringBuilder sb = new();
//             for (int i = 0; i < count; i++) {
//                 sb.Append(span[i].ToString());
//                 sb.Append(" ");
//             }
//
//             return sb.ToString();
//         }
//     }
//
//     public class C2R_Login_Handler : AMessageHandler<C2R_Login, R2C_Login> {
//         protected override void Handle(C2R_Login message, Network network, long channelId, int rpcId) {
//             Debug.Log($"用户登陆, {message.account} {message.password}");
//             var response = new R2C_Login() {
//                 ip = "1.1.1.1",
//                 token = 31415926
//             };
//
//             this.Reply(response, network, channelId, rpcId);
//         }
//     }
//
//     public class C2R_Ping_Handler : AMessageHandlerMultithreading<C2R_Ping, R2C_Ping> {
//         // 使用多线程版本, 测得纯网络通讯的延迟
//         protected override void Handle(C2R_Ping message, Network network, long channelId, int rpcId) {
//             var now = DateTime.Now.Ticks / 10000;
//             using var response = Network.MessagePool.Rent<R2C_Ping>();
//             response.sendTC = now - message.sendDT;
//             response.responseDT = now;
//             response.str = message.str;
//
//             NetworkTest.c2s_ms_sum += response.sendTC;
//             NetworkTest.c2s_ms_count += 1;
//             NetworkTest.c2s_ms = NetworkTest.c2s_ms_sum / NetworkTest.c2s_ms_count;
//             if (response.sendTC > 100) {
//                 NetworkTest.c2s_ms_big_count++;
//             }
//
//             Interlocked.Increment(ref NetworkTest.c2s_recvCounter);
//             Interlocked.Increment(ref NetworkTest.s2c_sendCounter);
//
//             this.Reply(response, network, channelId, rpcId);
//         }
//     }
//
//     public class C2R_Say_Handler : AMessageHandlerMultithreading<C2R_Say> {
//         protected override void Handle(C2R_Say message, Network network, long channelId) {
//             var now = DateTime.Now.Ticks / 10000;
//             var v = now - message.sendDT;
//             NetworkTest.c2s_ms_sum += v;
//             NetworkTest.c2s_ms_count += 1;
//             NetworkTest.c2s_ms = NetworkTest.c2s_ms_sum / NetworkTest.c2s_ms_count;
//             if (v > 100) {
//                 NetworkTest.c2s_ms_big_count++;
//             }
//
//             if (NetworkTest.Instance.checkMsgAccuracy && NetworkTest.Instance.protocol == NetworkTest.ProtocolKind.Kcp) {
//                 if (!NetworkTest.sayQueue.TryGetValue(channelId, out var queue))
//                     Log.Error("cuo l~");
//                 else {
//                     var succ = false;
//                     var count = queue.Count;
//                     while (count-- > 0) {
//                         queue.TryDequeue(out var say);
//                         if (say.Equals(message)) {
//                             succ = true;
//                             break;
//                         }
//                         else {
//                             queue.Enqueue(say);
//                         }
//                     }
//
//                     if (!succ)
//                         Log.Error("cuo l~");
//                 }
//             }
//
//             Interlocked.Increment(ref NetworkTest.c2s_recvCounter);
//         }
//     }
//
//
//     [MemoryPackable]
//     [MessageRequest(typeof(R2C_Login))]
//     public partial struct C2R_Login : IRpcMessage {
//         public string account;
//         public string password;
//     }
//
//     [MemoryPackable]
//     [MessageResponse]
//     public partial struct R2C_Login : IRpcMessage {
//         public string ip;
//         public int token;
//         public int uniqueId;
//     }
//
//     [MemoryPackable]
//     [MessageRequest(typeof(R2C_Ping))]
//     public partial class C2R_Ping : DisposableMessage, IRpcMessage {
//         public long sendDT;
//         public string str;
//
//         protected override void OnDisposed() {
//             this.sendDT = 0;
//             this.str = null;
//         }
//     }
//
//     [MemoryPackable]
//     [MessageResponse]
//     public partial class R2C_Ping : DisposableMessage, IRpcMessage {
//         public long sendTC;
//         public long responseDT;
//         public string str;
//
//         protected override void OnDisposed() {
//             this.sendTC = 0;
//             this.responseDT = 0;
//             this.str = null;
//         }
//     }
//
//     [MemoryPackable]
//     [Message]
//     public partial struct C2R_Say : INotifMessage, IEquatable<C2R_Say> {
//         public long sendDT;
//         public string msg;
//
//         public bool Equals(C2R_Say other) {
//             return this.sendDT == other.sendDT && this.msg == other.msg;
//         }
//
//         public override bool Equals(object obj) {
//             return obj is C2R_Say other && this.Equals(other);
//         }
//
//         public override int GetHashCode() {
//             return HashCode.Combine(this.sendDT, this.msg);
//         }
//     }
// }